const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const RecipeCategory = require('./recipeCategory.model');
const Food = require('./food.model');

/**
 * 食谱模型
 */
const recipeSchema = new Schema({
  title: {
    type: String,
    required: [true, '食谱标题不能为空'],
    trim: true,
    maxlength: [100, '食谱标题不能超过100个字符']
  },
  description: {
    type: String,
    required: [true, '食谱描述不能为空'],
    trim: true,
    maxlength: [2000, '食谱描述不能超过2000个字符']
  },
  coverImage: {
    type: String,
    required: [true, '封面图片不能为空'],
    trim: true
  },
  category: {
    _id: {
      type: Schema.Types.ObjectId,
      ref: 'RecipeCategory',
      required: [true, '分类ID不能为空']
    },
    name: String
  },
  difficulty: {
    type: Number,
    required: [true, '难度等级不能为空'],
    min: [1, '难度等级最小为1'],
    max: [5, '难度等级最大为5']
  },
  prepTime: {
    type: Number,
    required: [true, '准备时间不能为空'],
    min: [0, '准备时间不能小于0']
  },
  cookTime: {
    type: Number,
    required: [true, '烹饪时间不能为空'],
    min: [0, '烹饪时间不能小于0']
  },
  servings: {
    type: Number,
    required: [true, '份量不能为空'],
    min: [1, '份量最小为1']
  },
  ingredients: [{
    food: {
      _id: {
        type: Schema.Types.ObjectId,
        ref: 'Food',
        required: [true, '食材ID不能为空']
      },
      name: String
    },
    amount: {
      type: Number,
      required: [true, '食材用量不能为空'],
      min: [0, '食材用量不能小于0']
    },
    unit: {
      type: String,
      required: [true, '食材单位不能为空'],
      trim: true
    }
  }],
  steps: [{
    description: {
      type: String,
      required: [true, '步骤描述不能为空'],
      trim: true
    },
    image: String,
    duration: {
      type: Number,
      min: [0, '步骤时长不能小于0']
    }
  }],
  tips: [{
    type: String,
    trim: true
  }],
  nutrition: {
    calories: {
      type: Number,
      min: [0, '卡路里不能小于0']
    },
    protein: {
      type: Number,
      min: [0, '蛋白质不能小于0']
    },
    fat: {
      type: Number,
      min: [0, '脂肪不能小于0']
    },
    carbohydrates: {
      type: Number,
      min: [0, '碳水化合物不能小于0']
    }
  },
  tags: [{
    type: String,
    trim: true
  }],
  author: {
    _id: {
      type: Schema.Types.ObjectId,
      ref: 'Admin',
      required: [true, '作者ID不能为空']
    },
    name: String,
    username: String
  },
  viewCount: {
    type: Number,
    default: 0,
    min: [0, '浏览次数不能小于0']
  },
  likeCount: {
    type: Number,
    default: 0,
    min: [0, '点赞次数不能小于0']
  },
  favoriteCount: {
    type: Number,
    default: 0,
    min: [0, '收藏次数不能小于0']
  },
  isVerified: {
    type: Boolean,
    default: false
  },
  isDeleted: {
    type: Boolean,
    default: false
  },
  deletedAt: {
    type: Date,
    default: null
  }
}, {
  timestamps: true
});

// 添加索引
recipeSchema.index({ title: 'text', description: 'text' });
recipeSchema.index({ isDeleted: 1, isVerified: 1 });
recipeSchema.index({ 'category._id': 1 });
recipeSchema.index({ 'author._id': 1 });
recipeSchema.index({ viewCount: -1 });
recipeSchema.index({ likeCount: -1 });
recipeSchema.index({ favoriteCount: -1 });
recipeSchema.index({ createdAt: -1 });

// 验证分类ID是否存在
recipeSchema.pre('save', async function(next) {
  try {
    // 如果分类信息没有更改，跳过验证
    if (!this.isModified('category._id')) {
      return next();
    }

    const category = await RecipeCategory.findById(this.category._id);
    
    if (!category) {
      throw new Error('分类不存在');
    }

    if (category.isDeleted) {
      throw new Error('分类已被删除');
    }

    if (!category.isActive) {
      throw new Error('分类已被禁用');
    }

    // 更新分类名称
    this.category.name = category.name;
    next();
  } catch (error) {
    next(error);
  }
});

// 验证食材ID是否存在
recipeSchema.pre('save', async function(next) {
  try {
    // 如果食材列表没有更改，跳过验证
    if (!this.isModified('ingredients')) {
      return next();
    }

    const foodIds = this.ingredients.map(ing => ing.food._id);
    const foods = await Food.find({ _id: { $in: foodIds } });
    
    if (foods.length !== foodIds.length) {
      throw new Error('部分食材不存在');
    }

    // 更新食材名称
    const foodMap = new Map(foods.map(food => [food._id.toString(), food]));
    this.ingredients.forEach(ing => {
      const food = foodMap.get(ing.food._id.toString());
      if (food) {
        ing.food.name = food.name;
      }
    });

    next();
  } catch (error) {
    next(error);
  }
});

module.exports = mongoose.model('Recipe', recipeSchema); 